package com.rndemo.db;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.TextUtils;

import com.facebook.react.bridge.Argument;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import com.rndemo.annotations.FieldTag;
import com.rndemo.annotations.FieldType;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by tzj on 2018/5/28.
 */
public class JsDB extends BaseDB{
    @FieldTag(type = FieldType.ignore)
    private Bundle mBundle;
    @FieldTag(type = FieldType.ignore)
    private Callback onUpgrade;

    public JsDB(Bundle mBundle, Callback onUpgrade) {
        super(mBundle);
        this.mBundle = mBundle;
        this.onUpgrade = onUpgrade;
        if(getDbHelper()==null){
            map.put(getClass(),new SQLiteDelegate(this));
        }
    }

    @Override
    public List select(String where, String... data) {
        String sql = null;
        if(where == null){
            sql = "select * from " + dbName();
        }else {
            sql = "select * from " + dbName() + " where " + where;
        }
        List ret = new ArrayList<WritableNativeMap>();
        Cursor cursor = getDbHelper().getReadableDatabase().rawQuery(sql, data);
        if (cursor == null) {
            return ret;
        }
        while (cursor.moveToNext()) {
            try {
                WritableMap map = Argument.createMap();
                filling(map,cursor);
                ret.add(map);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        cursor.close();
        return ret;
    }

    @Override
    public String dbPath() {
        if(TextUtils.isEmpty(mBundle.getString("path"))){
            return dbName();
        }
        return super.dbPath();
    }

    @Override
    public String dbName() {
        return mBundle.getString("name");
    }
    @Override
    public int version() {
        return (int) mBundle.getInt("schemaVersion");
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        super.onUpgrade(db, oldVersion, newVersion);
        onUpgrade.invoke(oldVersion,newVersion);
    }

    @Override
    protected Map<String, String> toDb(Class<?> c) {
        Bundle bundle = mBundle.getBundle("properties");
        String primaryKey = mBundle.getString("primaryKey");
        Iterator<String> iterator = bundle.keySet().iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            String value = bundle.getString(next);
            if(primaryKey!=null && primaryKey.equalsIgnoreCase(value)){
                value+=" primary key";
            }
            objFiles.put(next,bundle.getString(next));
        }
        return objFiles;
    }


    private void filling(WritableMap map, Cursor cursor) {
        Iterator<String> iterator = objFiles.keySet().iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            int columnIndex = cursor.getColumnIndex(next);
            String type = objFiles.get(next);
            if (type.startsWith("text") || type.startsWith("varchar") || type.startsWith("string")) {
                map.putString(next, cursor.getString(columnIndex));
            } else if (type.startsWith("int")) {
                map.putInt(next, cursor.getInt(columnIndex));
            } else if (type.startsWith("double") || type.startsWith("datetime") || type.startsWith("long") || type.startsWith("float")) {
                map.putDouble(next, cursor.getDouble(columnIndex));
            } else if (type.startsWith("boolean")) {
                map.putBoolean(next, cursor.getInt(columnIndex) > 0 ? true : false);
            }
        }
    }
}
